from tparser.model import DeclarativeBase
from sqlalchemy import Column, ForeignKey, Index, Integer, String, DateTime, Date, Time, Float, Enum, Boolean
from sqlalchemy.sql import func
from sqlalchemy.orm import relation, backref

from tparser.model.trip_plan import TripPlan
from tparser.model.coordinate import Coordinate

class OriginDestinationStudy(DeclarativeBase):
    '''OD Study is a table to load in an existing OD Study data, which can then be used to plan trips 
    '''
    __tablename__ = 'origin_destination_study'
    id = Column(Integer, primary_key=True)

    route = Column(String)
    direction = Column(String)
    service_key = Column(String)
    time = Column(Time)

    num_transfers = Column(Integer)

    origin_name = Column(String)
    origin_city = Column(String)
    origin_lat = Column(Float)
    origin_lon = Column(Float)

    destination_name = Column(String)
    destination_city = Column(String)
    destination_lat = Column(Float)
    destination_lon = Column(Float)

    created = Column(DateTime, default=func.current_timestamp())

    trip_id  = Column(
        Integer,
        ForeignKey(TripPlan.id),
        nullable=True
    )

    # single table inheritance stuff that identifies  
    discriminator = Column('type', String(50))
    __mapper_args__ = {'polymorphic_on': discriminator}

    def get_trips(self):
        '''should be a generic routine to get trips out of the database (either from OD study or saved trips)'''

class TriMetODStudy(OriginDestinationStudy):


    '''@see http://www.sqlalchemy.org/docs/05/reference/ext/declarative.html#single-table-inheritance
        Idea of TriMetODStudy is to extend the Parent OD study with attributes specific to TM's OD study

        NOTE: the columns must be differently named
    '''
    __mapper_args__ = {'polymorphic_identity': 'trimet'}

    qxnum = Column(String)
    year = Column(String)
    bus_max_streetcar = Column(String)
    time_of_day = Column(String)
    boarding_factor = Column(String)
    originating_factor = Column(String)
    fare_type = Column(String)
    fare_cost = Column(String)

    # need to reporoject these to lon/lat
    origin_x = Column(Float)
    origin_y = Column(Float)
    destination_x = Column(Float)
    destination_y = Column(Float)

    def _fixup(self):
        '''record_fix overrides the base-class method to manipulate data specifically for TriMet
           operations: 
               OSPN X/Y -> lat/lon re-projection
               funky trimet time_of_day enum is replaced with approx. times of day
               etc...
        '''
        self.origin_lon, self.origin_lat = Coordinate.statePlaneNorthToLL(self.origin_x, self.origin_y)
        self.destination_lon, self.destination_lat = Coordinate.statePlaneNorthToLL(self.destination_x, self.destination_y)


class CTranODStudy(OriginDestinationStudy):
    '''@see http://www.sqlalchemy.org/docs/05/reference/ext/declarative.html#single-table-inheritance
        Idea of CTranODStudy is to extend the Parent OD study with attributes specific to C-Tran's OD study
        
        NOTE: 
    '''
    __mapper_args__ = {'polymorphic_identity': 'c-tran'}
    primary_language = Column(String)
    second_language = Column(String())
